package com.sky.happygos.YiPush;

import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;

import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Response;

/**
 * Created by qqqqqqq on 2017/4/7.
 */

public class YiPush {
    private String host;
    private int port;

    public TcpClient tcpClient;
    private Handler handler;
    private String userid;
    private Gson gson;
    private static YiPush instanse;

    public static Builder builder(){
        return new Builder();
    }

    public static  YiPush getInstanse(){
        return instanse;
    }

    private YiPush(){

    }
    private void init(){
        gson = new Gson();
        handler = new Handler(){
            @Override
            public void dispatchMessage(Message msg) {
                super.dispatchMessage(msg);
                if(msg.arg1 == 666){
                    receiveMessageCallBack.connectCallBack(true);
                }else {
                    Proto p = (Proto) msg.obj;
                    if (receiveMessageCallBack != null) {
                        Msg m = gson.fromJson(p.data, Msg.class);
                        receiveMessageCallBack.receiveMessage(m);
                    }
                }
            }
        };
        tcpClient = new TcpClient(host,port,handler);
        tcpClient.setUserid(userid);
        instanse = this;
    }

    public Msg pushMessage(final Msg msg, final StatusCallBack callBack){
        msg.from = userid;
        String json = gson.toJson(msg);
        try {
            tcpClient.pushMessage(json, new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    callBack.status(e.toString());
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    String json = response.body().string();
                    String status = gson.toJson(json);
                    callBack.status(status);
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return msg;
    }
    public Msg pushMessageToRoom(Msg msg, final StatusCallBack callback){
        String json = gson.toJson(msg);
        try {
            tcpClient.pushMessageToRoom(json,new Callback(){

                @Override
                public void onFailure(Call call, IOException e) {
                    callback.status(e.toString());
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    String json = response.body().string();
                    String status = gson.toJson(json);
                    callback.status(status);
                }
            });
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
        return msg;
    }


    public void getMessages(String to, MsgCallBack callback){
        getMessages(to,"",callback);
    }

    public void getMessages(String to, String type, final MsgCallBack callback){
        try {
            tcpClient.getMsgs(to,type, new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    callback.msgs(new ArrayList<Msg>());
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    String jsonMsgs = response.body().string();
                    List<Msg> msgs = gson.fromJson(jsonMsgs,
                            new TypeToken<List<Msg>>() {
                            }.getType());

                    for (Msg msg:
                         msgs) {
                        msg.isMe = msg.from.equals(userid);
                    }
                    callback.msgs(msgs);

                }
            });


        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public void getOnlineUsers(final UserCallBack userCallBack){
        try {
            tcpClient.getOnlineUser(new Callback() {
                @Override
                public void onFailure(Call call, IOException e) {
                    userCallBack.users(new ArrayList<String>());
                }

                @Override
                public void onResponse(Call call, Response response) throws IOException {
                    String jsonMsgs = response.body().string();
                    List<String> users = gson.fromJson(jsonMsgs,
                                    new TypeToken<List<String>>() {
                                    }.getType());
                    userCallBack.users(users);
                }
            });

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public boolean joinRoom(String roomid) {
        return tcpClient.joinRoom(roomid);
    }

    public boolean leaveRoom(String roomid){
        return tcpClient.leaveRoom(roomid);
    }



    public void startServiceThread(){
        tcpClient.start();
    }

    public void start(Context context){
        instanse = this;
        Intent intent = new Intent(context,PushService.class);
        intent.putExtra("EXTRA_PUSH_HOST",host);
        intent.putExtra("EXTRA_PUSH_PORT",port);
        intent.putExtra("EXTRA_PUSH_USERID",userid);
        intent.setPackage(context.getPackageName());
        context.startService(intent);

    }

    public interface UserCallBack{
        void users(List<String> users);
    }
    public interface StatusCallBack{
        void status(String status);
    }
    public interface MsgCallBack{
        void msgs(List<Msg> msgs);
    }

    public interface YiPushCallBack{
        void receiveMessage(Msg msg);
        void connectCallBack(boolean status);
    }
    private YiPushCallBack receiveMessageCallBack;

    public static class Builder {
        private String host;
        private int port;
        private String userid;
        private YiPushCallBack receiveMessageCallBack;
        public Builder setPushServer(String host, int port){
            this.host = host;
            this.port = port;
            return this;
        }
        public Builder setReceiveMessageCallBack(YiPushCallBack receiveMessageCallBack){
            this.receiveMessageCallBack = receiveMessageCallBack;
            return this;
        }
        public Builder setUserid(String userid){
            this.userid = userid;
            return this;
        }
        public YiPush build(){
            YiPush yiPush = new YiPush();
            yiPush.host = this.host;
            yiPush.port = this.port;
            yiPush.userid = this.userid;
            yiPush.receiveMessageCallBack = receiveMessageCallBack;
            yiPush.init();
            return yiPush;
        }
    }
}
